SUPER MARIO BROS. 3 MUSIC FORMAT v1.1 By Justin Olbrantz (Quantam) The permanent home of this specification and others, with the latest updates, is https://github.com/TheRealQuantam/RetroDocs. This specification describes the music engine used by Super Mario Bros. 3, the last game released on the Nintendo Entertainment System by Nintendo's Research and Development 4, the group famous for legendary game designer Shigeru Miyamoto and composer Koji Kondo and responsible for the Super Mario and Legend of Zelda franchises. From the perspective of a music hacker, the R&D4 group is also famous for its distinctive music engines. While there is some variation in encoding between games, all of R&D4's NES engines share some common features which combine to make them outright hostile to romhackers seeking to insert their own music into the games and tool makers who might try to make this process easier. First, R&D4 engines are EXTREMELY basic. While engines by other companies typically have robust, flexible engines designed to give maximum flexibility to the composer and allow the engine to be used with little to no modification in many games with many types of music, R&D4 engines are typically hybrid systems that combine basic note data with hard-coded hardware settings that provide the special sauce for each game's distinctive sound. These engines typically only have 3 event types: notes, rests, and set note length commands; if you're lucky there might be a set timbre or portamento command, as in SMB3, or timbre might be hard-coded in the engine, as in earlier R&D4 games. Second, R&D4 uses a track format unlike anything I've seen from other companies or groups - a format which seems to have anachronistic origins tracing back to Nintendo's very first NES game. While it is standard practice to separate track data into hardware channels to allow for compression structures such as loops to take full advantage, the primary division of data in R&D4 engines is time. In a structure reminiscent of trackers such as FamiTracker, data for all channels is bundled together into blocks of varying duration, and these blocks are then strung together into a complete track by a global block playlist; segments of music data are repeated not by any kind of loop structure, but simply by putting the block in the playlist multiple times. This rigid structure places many constraints on romhackers that are absent in non-R&D4 formats. Basic Features: - Single byte notes and rests, though current note length must be previously defined with an additional byte + Hybrid tempo system that mimics staff notation style divisive rhythm - 5-octave chromatic scale from A#1 (58.27 Hz) to D7 (2349 Hz) for square wave (triangle is 1 octave lower). - 13 note lengths from whole notes through 16th notes with dots and triplets for some lengths for all tempos, plus several tempo-specific lengths - 10 tempos ranging from 112.5 to 450 BPM - 5 channels - square 1, square 2, triangle, noise, and DMC - each with separate event sequences + Multi-timbre support - 8 square timbres with non-looping duty cycle/volume envelopes, plus 1 hard-coded timbre using pitch slide - 3 percussion noise presets - 16 DMC percussion presets on 9 instruments - Rising portamento for the square channels + Tracker-like block structure - Track data divided first by time, then channel - Variable-duration blocks of fixed maximum physical size - Tracks constructed of a playlist of blocks - Single tempo per block Some general notes in interpreting this specification: - All word (16-bit) values in the format are little-endian, with the least-significant byte preceding the most-significant. - All values are unsigned unless noted otherwise. - All numbers preceded by $ are hex, and in general unless they represent byte strings or addresses most numbers without $ are in decimal. - Byte values are generally shown as hex "ab" where "a" is the high nibble and "b" is the low nibble (standard mathematical digit ordering). When it is necessary to show bit fields, bytes are shown in binary as "abcd efgh" (again mathematical order); in bit fields "-" means that the value of the bit does not matter in the given context. - Many command lists (e.g. channel data commands) are encoded ambiguously, where 1 value could be interpreted as multiple different commands (e.g. 00 could also match 0n). These lists are ordered such that the first matching command is the correct interpretation. - A wave's "period" is inversely proportionate to its frequency; in the NES the square wave channel's period = 1789773/16 / frequency (triangle channel is 1 octave lower for the same period), and the value actually written to the hardware is 1 less than this. Here "pitch" is used as proportionate to key number, is what humans perceive, and frequency doubles (period halves) with each pitch increase of 1 octave. As such "linear period", "linear frequency", and "linear pitch" are all very different things, and linear pitch is what sounds linear to the ear. Track Format Tracks are formatted in a 4-level hierarchical structure - 5 if you include the individual channels: 1. Track table 2. Block header offset table 3. Block header blocks 4. Music blocks 5. Channel data At the highest level is the track table. Each track entry consists of 3 values (though in fact it's actually 3 parallel arrays of values): first block index, last block index, and loop block index, which define which blocks belong to the track and how to loop at the end of the track. However, as block headers (to be described shortly) are ALSO packed into 256-byte blocks, there are in fact 2 track tables needed to hold all the tracks for the game, which are here referred to as bank 1 (or the "low" bank) and bank 2 (the "high" bank); note that this use of "bank" is distinct from the ROM bank, and the 2 meanings generally do not coincide. The track block indices index into the second level of structure: the block header offset table. This table is an array of bytes which specify the location of each block header within the block of block headers (*cough*); it is because these are byte-sized offsets within the block that there can only be so many block headers in said block, requiring 2 different track tables and likewise 2 different block offset tables. This table also doubles as the playlist of blocks: a track begins at the specified first block and proceeds sequentially through this table until it finishes playing the specified last block, at which point the track either ends or loops back to the specified loop block. The first 8 entries in the bank 1 block offset table are fanfares, though #8 is in fact an empty track used to stop music playback. Fanfares are short, non-looping, single-block tracks that interrupt side-scrolling background music to play in events such as death or level completion and the prior track is usually resumed afterwards (though the restart mechanism only supports bank 2 tracks and bank 1 tracks 9 and $a). Fanfares 1-8 are mapped directly to block offset entries 1-8 in bank 1, and have no separate track table. Fanfare 7 is the "time is running out" fanfare, and is hard-coded in the engine to increase the tempo of the track it resumes to by 1 level (see the list of tempos) until the end of that track. The third layer of structure, then, are the block headers. These headers specify 3 key pieces of information: the address of the block, the tempo of the block (R&D4 engines have no explicit commands to set the tempo, only the value in the block header), and the starting locations of the square 1, triangle, noise, and DMC channel data within the block; square 2 is the master channel and is always located at the very beginning of the block. This leaves a small window for shenanigans. It might occasionally be useful to share data from specific channels between blocks; this is done in 1 track from SMB3, for instance. This is possible in a very limited way: it is possible for 2 block headers to refer to the same block data by address, but provide different tempo or channel data offsets. This requires careful layout of data as all data used by a block header must be in a 256-byte window (we'll call it a virtual block). This is especially tricky since the block address also specifies the square 2 data location, requiring the square 2 data to always precede the data for the other channels for all virtual blocks and the offsets to the other channels to be relative to the start of the square 2 channel. However, the reason the square 2 channel is called the master channel goes beyond its location within the block: the square 2 channel is the only channel whose block data is explicitly terminated and thus determines the duration of the block as a whole; when the end of the square 2 channel data for a block is reached, all channels advance to the next block (if any) together. The effect of shorter durations between channels varies by channel. The square 1 and triangle channels MUST be the same duration as the square 2 channel. But for the noise and DMC channels, given how common it is to compose tracks with short, repetitive drum loops underneath more lengthy melodies, the noise and DMC channel data will be looped infinitely until the end of the square 2 block data is reached. To summarize, a virtual block: - Is defined by a block header - Has a single specified tempo - Defines the locations of each channel's data within the virtual block - May be of any length of time, but... - May be at most 256 bytes for all channel data combined and begins with the square 2 data - Will repeat its noise and DMC channel data if said data is shorter than the square 2 data, allowing short drum loops to be used under longer melodies - May overlap with other virtual blocks if you're evil - Is a true "block" if it does not overlap any other blocks The following additional constraints also exist to make romhacking harder: - 2 banks of tracks - 15 tracks in bank 1, 12 tracks in bank 2 (though track 12 is unused) - First 8 entries in the block header offset table for bank 1 are fanfares - Bank 1 has space for $2c entries in its block header offset table (i.e. the playlist size) and $24 block headers (though 2 headers partially overlap), bank 2 has space for $2d entries in its block header offset table and $25 block headers. - Theoretical maximum of $ff block header offset entries and $25 block headers per bank if structures are relocated All music code and data is stored in ROM banks $1c/$1d at $a000-dfff and bank $1f at $e000-$ffff. To convert addresses to file offsets: For addresses $a000-$dfff: file offset = addr + $2e010 For addresses $e000-$ffff: file offset = addr + $30010 IMPORTANT NOTE: The SMB3 engine is very unusual in that it uses 1-based indices for its arrays such as the track list, and it is documented likewise here. This means all array addresses given, unless noted otherwise, are actually 1 element BEFORE the first element in the list, and numbers such as track numbers begin with 1. Block Header Structure: +0 byte: tttt 0000: Tempo index t. Tempos (in BPM): 0: 112.5, 1: 120, 2: 128.6, 3: 150, 4: 180, 5: 200, 6: 225, 7: 257.1, 8: 300, 9: 450 +1 word: Block start address: square 2 channel address +3 byte: Triangle block offset or 0 if none +4 byte: Square 1 block offset +5 byte: Noise block offset or 0 if none +6 byte: DMC block offset or 0 if none Example block header: 30 B1 AB 26 11 00 38 30: t = 3: Tempo 3 (150 BPM) B1 AB: Block (and square 2 channel data) start address $abb1 26: Triangle data block offset $26 11: Square 1 data block offset $11 00: No noise channel data for this block 38: DMC channel data offset $38 Bank 1: 1C:a73f byte[$2c]: Block header offset table 1C:a76c structs ($101 bytes): Block headers block. Note that this is NOT an array, and block headers are not necessarily aligned. 1C:a86c byte[$f]: 0-based first track block index 1C:a87b byte[$f]: 0-based last track block index 1C:a88a byte[$f]: 0-based loop track block index, or 0 if no loop Bank 2: 1C:b3ff byte[$2d]: Block header offset table 1C:b42d structs ($103 bytes): Block headers block. Same caveats. 1C:b52f byte[$c]: 0-based first track block index 1C:b53b byte[$c]: 0-based last track block index 1C:b547 byte[$c]: 0-based loop track block index, or 0 if no loop NOTE: The track block indices given in the above arrays are 0-based, while the block header offset tables (as well as the track block index tables themselves) are accessed with 1-based indices. E.g. for bank 1's first track, 1C:b530 (index 1 of the first track block index table) = 8; this block's header offset can then be found at 1C:a748 (index 9 of the block header offset table). This means it is impossible for a track to loop to block 1, as that would be a loop block index of 0, which means no loop. See the Additional Tables section for information on relocating these structures. Time and Tempo As already stated, SMB3 supports the following tempos in BPM: 0: 112.5, 1: 120, 2: 128.6, 3: 150, 4: 180, 5: 200, 6: 225, 7: 257.1, 8: 300, 9: 450. The SMB3 engine uses a hybrid of tempo and frame counting. Note lengths are converted at note start to frames the note should play at that tempo. This produces lengths of fractional frames at some length/tempo combinations, which the engine cannot directly deal with. This is handled by the primary/secondary system, in which the relevant lengths are assigned 2 length codes, a primary and a secondary, and a complete tuplet using these codes will produce the correct number of frames the tuplet should play combined. A triplet is made of 2 primary and 1 secondary length notes. A doublet of 16ths has 1 primary and 1 secondary length note, though at tempos where the primary and secondary lengths are the same, Kondo often does not distinguish between the 2. At some tempos this can be exploited for a very slight swing rhythm; for more information see the full note length table in Additional Tables. Note Length Codes (pairs are primary/secondary): Whole Half 4th 8th 16th Normal: c a 8 4 0/1 Dotted: b 9 5 Triplet: 6/7 2/3 Triangle channel notes may auto-release (be silenced) prior to the beginning of the next event. When a note begins, after the length of the note in frames is calculated, the triangle's linear counter is set based on the note length as follows: Note duration is 1-9 frames: linear counter set to $18 quarter-frames (~6 frames) $a-$12: $20 (~8 frames) $13-$24: $50 (~$14 frames) $25+: $ff (no auto-release) See the Additional Tables section for information on changing these lengths. Notes and Keys SMB3 uses 3 different key sets: 1 for the melodic channels, 1 for the noise channel, and 1 for the DMC channel. The melodic channels all use the same key set save that the triangle channel is 1 octave lower than the square channels for the same key code. The melodic key table, giving octave numbers for the square channels: Oct C C# D D# E F F# G G# A A# B Max Detune at Bx 1: 7d* 7e* 7f* 0.96 cents 2: 0* 1 2 3 4 5 6 7 8 9 a b 1.91 cents 3: c d e f 10 11 12 13 14 15 16 17 3.83 cents 4: 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 7.66 cents 5: 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 15.4 cents 6: 30 31 32 33 34 35 36 37 38 39 3a 3b 30.8 cents 7: 3c 3d 3e 36.7 cents at D7 Notes: - C2 is 65.41 Hz - Detune figures are for the actual octaves listed. As such for the triangle channel the appropriate detune value is in the row above the corresponding row of key values, e.g. the detune value for $17 (B2) on triangle would actually be 1.91 cents. - Keys with * are an exploit that requires that the note event either IMMEDIATELY follow an attributes command or be the target key of a portamento. Additionally, key 0 is ONLY possible on square 2 channel. The noise channel has 3 presets. It is not readily apparent what they are supposed to be, so only their basic characteristics will be given. Note that pitch is the value written to the NES' registers, and that number of frames refers to the maximum length of the sound and it will be cut short if the note duration is shorter: # Vol Pitch # Frames 1 $e 3 2 2 $f $a 2 3 $f 2 $a The preset list for the DMC channel is as follows: 1: Bass/kick drum 2: Snare drum short 3: Snare rim 4: Snare drum long (appears to be buggy and can play garbage data on longer notes) 5: Wood block 6: Bongo high 7: Bongo mid 8: Timbales high 9: Timbales low a: Synth pad high b: Synth pad low c: Bongo low d: Clap e: Timpani high f; Timpani mid 10: Timpani low Channel Data Format Compared to other engines, and even compared to the track structure, channel data is extremely simple. The format differs slightly between channels, but the basic 3 commands are the same: play note, rest, and set note attributes, which sets the length for subsequent notes/rests and for the square channels the timbre. The square channels additionally have the ability to perform portamento between 2 notes, but this has limitations. Square Channel Data Format: 00: Channel-specific: Square 2: End of block Square 1: Set ctrl 2 to $94 for the rest of the block. This is used in fanfare 1 (death). 7e: Rest for the current note duration. Sets the envelope to sustain: the envelope position is set to its last entry - which is silence for most envelopes - which is continued until the next note command. ff 0KKK KKK0: Portamento target: IMMEDIATELY following a note: Modifies the previous note (only a single note duration occurs for the whole thing) to play linear period portamento from previous key k to K (K > k). The pitch rises (period decreases) at a rate of 3/4 period units per frame. Portamento will NOT work properly (if at all) if the target key is lower than the base key or if the portamento crosses a $100-period boundary above B1, below D2, ~F2, below A2, below D3, below A3, or below A4. After anything else: Does nothing and should not be used 1ttt LLLL: Note attributes. Sets timbre number to t (0-7) and note length code to L for subsequent notes. MUST NOT be immediately followed by another attributes command. 0kkk kkk0: Play key k for the current note duration Triangle Channel Data Format: 00: Pseudo-rest for the current note duration. Silences channel after 1/4 frame. Probably a bug rather than a feature. 7e: Rest for the current note duration. Silences channel. 8L (1--- LLLL): Set note length code to L for subsequent notes, subject to auto-release. MUST NOT be immediately followed by another length command. 0kkk kkk0: Play key k for the current note duration Noise Channel Data Format: 00: Loop. Restart noise events for this block. 01: Rest for the current note duration. Silences channel. This actually plays noise preset 0, which sets the noise channel volume to 0. 8L (1--- LLLL): Set note length code to L for subsequent notes. MUST NOT be immediately followed by another length command. 0000 0kk-: Play noise preset k (1-3) for the current note duration. DMC Channel Data Format: 00: Loop. Restart DMC events for this block. 7e: Rest for the current note duration. Silences channel. 8L (1--- LLLL): Set note length code to L for subsequent notes. MUST NOT be immediately followed by another length command. 000k kkkk: Note. Play DMC sound k (1-$10) for the current note duration. Examples Square 2 Channel (the tempo for this block is 3: 150 BPM): 94 (1001 0100): Set attributes t = 1: Timbre 1 L = 4: 8th note. 12 frames at this tempo resulting in the short envelope (explained in the Timbre section). 54: Note k = $2a: Key F#5 5C FF 5E: Portamento k = $2e: Initial key A#5 K = $2f: Final key B5 00: End of block Square 1 Channel (the tempo for this block is 0: 112.5 BPM): 90 (1001 0000): Set attributes t = 1: Timbre 1 L = 0: 16th note primary, 8 frames at this tempo (at this tempo 16th primary and secondary are the same length). Short envelope will be used. 60: Note k = $30: C6 62: Note k = $31: C#6 94 (1001 0100): Set attributes t = 1: Timbre 1 L = 4: 8th note, 16 frames at this tempo. Short envelope will be used. 7e: Rest 98 (1001 1000): Set attributes t = 1: Timbre 1 L = 8: Quarter note, 32 frames at this tempo. Long envelope will be used. Triangle Channel (the tempo for this block is 3: 150 BPM: 88: Set length L = 8: Quarter note, 24 frames at this tempo. Linear counter will be set to $50: ~20 frames until auto-release. 26: Note k = $13: Key G2 (triangle is 1 octave lower) 8C: Set length L = $c: Whole note, 96 frames at this tempo. Linear counter will be set to $ff: no auto-release. 3C: Note k = $1e: Key F#3 9B: Not actually part of this channel because the square 2 channel data ends the block at the end of the previous note. Noise Channel (the tempo for this block is 4: 180 BPM): 94: Set length L = 4: 8th note, 10 frames at this tempo 02 x 2: Notes k = 1: Noise preset 1 06: Note k = 3: Noise preset 3 02: Note k = 1: Noise preset 1 00: Loop. The full block is in fact 320 frames, so this 40-frame loop will play 8 times. DMC Channel (the tempo for this block is 0: 112.5 BPM): 98: Set length L = 8: Quarter note, 32 frames at this tempo 05: Note k = 5: Wood block 00: Loop. The full block is 256 frames, so this 32-frame loop will play 8 times. As can be seen, square 1 and triangle channels are never explicitly terminated, while noise and DMC channels need only be explicitly terminated when they loop before square 2 data ends. Square Wave Timbres Square wave timbres in SMB3 consist of a simple non-looping envelope of ctrl 1 ($4000, $4004) values including both duty cycle and volume; each value in the envelope table is played for 1 frame, and the final value is sustained indefinitely (it is also used when a rest is encountered). There are long and short variants for each timbre: a short $17-entry envelope for notes shorter than $13 frames and a long $40-entry envelope for longer notes; which length is used is selected when each note begins and the length in frames is calculated. Notably, SMB3 envelope values are stored in reverse order, where entry 0 is the last entry. Interestingly, unlike most such envelopes in other engines, some SMB3 timbres actually vary their duty cycles during their early decay phase. Each byte value in the envelope has the format ddLV vvvv: d: Duty cycle. 0: 12.5%, 1: 25%, 2: 50%, 3: 75% L: Disable length counter and play note forever. Oddly, this is never set in SMB3, giving all notes a maximum duration of 127 frames. For SMB3 this generally has minimal impact, as only whole notes at the slowest tempo exceed this (128 frames), but this effect can be seen when a sustaining envelope note is followed by 1 or more rests. V: Specifies that v is the volume and not decay rate. Always set. v: The volume Example Short timbre 0 envelope: 90 92 94 95 95 95 95 95 95 95 95 95 95 95 95 95 95 96 96 15 17 58 1A 1A (0001 1010): d = 0: Duty cycle of 12.5% v = $a: Volume of 10 58 (0101 1000): d = 1: Duty cycle of 25% v = 8: Volume of 8 17 (0001 0111): d = 0: Duty cycle of 12.5% v = 7: Volume of 7 ... 90 (1001 0000): d = 2: Duty cycle of 50% v = 0: Silence, making this a non-sustaining envelope ADDITIONAL TABLES Master Note Length Table TDiv BPM 0 1 2 3 4 5 6 7 8 9 $a $b $c $d $e $f 16P 16S 8TP 8TS 8 8D 4TP 4TS 4 4D 2 2D 1 0 (16): 112.5: 8 8 b a 10 18 15 16 20 30 40 60 80 1 1f 0 1 (15): 120: 7 8 a a f 16 14 14 1e 2d 3c 5a 78 5 0 0 2 (14): 128.6: 7 7 9 a e 15 13 12 1c 2a 38 54 70 1 4 0 3 (12): 150: 6 6 8 8 c 12 10 10 18 24 30 48 60 4 2 16 4 (10): 180: 5 5 7 6 a f d e 14 1e 28 3c 50 3 1 13 5 (9): 200: 4 5 6 6 9 d c c 12 1b 24 36 48 1e 3 0 6 (8): 225: 4 4 5 6 8 c b a 10 18 20 30 40 0 0 0 7 (7): 257.1: 3 4 5 4 7 a 9 a e 15 1c 2a 38 b 0 0 8 (6): 300: 3 3 4 4 6 9 8 8 c 12 18 24 30 2 0 0 9 (4): 450: 2 2 3 2 4 6 5 6 8 c 10 18 20 ff ff ff Legend: TDiv: Tempo divider. BPM = 1800/TDiv. 1, 2, 4, etc.: Whole, half, quarter, etc. notes D: Dotted T: Triplet P: Primary (2 in a triplet) S: Secondary (1 in a triplet) Only entries 0-$c of each tempo are standardized while $d-$f are odd values, most of which aren't used and whose meaning, when any, varies by tempo. The following are the meanings of those that could be identified: TDiv BPM $d $e $f 0 (16): 112.5: 128 ? 1 (15): 120: 16T* 2 (14): 128.6: ? ? 3 (12): 150: 16T* 32T* ? 4 (10): 180: ? ? ? 5 (9): 200: 5*8T* 16T 6 (8): 225: 7 (7): 257.1: ? 8 (6): 300: 16T 9 (4): 450: ? ? ? * indicates that these tempo/length combinations are actually used in game. Length $d for tempo 5 is only ever used on the DMC channel, and occurs in pairs with length 2 (8T) to form a combined half-note. Code to read the note length from the table (bank $1f): E345 LDA $E874,Y Code to assign the triangle linear counter value based on the note length in frames: E696 CMP #$0A E698 BCC $E6A6 E69A CMP #$13 E69C BCC $E6AA E69E CMP #$25 E6A0 BCS $E6AE E6A2 LDA #$50 E6A4 BNE $E6B4 E6A6 LDA #$18 E6A8 BNE $E6B4 E6AA LDA #$20 E6AC BNE $E6B4 E6AE LDA #$FF E6B0 BNE $E6B4 E6B2 LDA #$80 E6B4 STA TrgLinear_4008 Square Channel Timbre Envelopes Each timbre has long and short variants. The short variant is used for notes shorter than $13 frames, and the long variant is used for longer notes. In most cases the long variant just has slower decay than the short variant, but timbres 2 and 3 have significant differences in their volume envelopes. 1f:e765 word[8]: Long envelope address table 1f:e775 word[8]: Short envelope address table To make it easier to read, the duty cycle envelope is separated from the volume envelope. Also, to make the envelopes more intuitive the order of entries is REVERSED to make time go from left to right; in the actual game, entry 0 in an envelope is the LAST entry. Short Timbre Envelopes: Timbre 0 @b1d6 (391e6): Duty cycle: 01002222222222222222222 Volume: a8756655555555555555420 Timbre 1 @b22d (3923d): Duty cycle: 01111111111111111111111 Volume: a9765432211100000000000 Timbre 2 @b284 (39294): Duty cycle: 22222222222222222222222 Volume: 89aa9875311100000000000 Timbre 3 @b2dc (392ec): Duty cycle: 22222222222222222222222 Volume: 88877000000000000000000 Timbre 4 @b2f3 (39303): Duty cycle: 11111111111111111111111 Volume: 33455666777765443332211 Timbre 5 @b34a (3935a): Duty cycle: 11111111111111111111111 Volume: a9876543211000000000000 Timbre 6 @b22d (3923d): Duty cycle: 01111111111111111111111 Volume: a9765432211100000000000 Timbre 7 @b3e1 (393f1): Duty cycle: 23011111111111111111111 Volume: ba987654321111111111110 Long Timbre Envelopes: Timbre 0 @b196 (391a6): Duty cycle: 0100222222222222222222222222222222222222222222222222222222222222 Volume: a875665555555555555555555555555555555555555555555555555555555420 Timbre 1 @b1ed (391fd): Duty cycle: 0111111111111111111111111111111111111111111111111111111111111111 Volume: a987665544333222111111000000000000000000000000000000000000000000 Timbre 2 @b244 (39254): Duty cycle: 2222222222222222222222222222222222222222222222222222222222222222 Volume: 789aa99988888888888888888888888888888777777766655554444332221110 Timbre 3 @b29c (392ac): Duty cycle: 2222222222222222222222222222222222222222222222222222222222222222 Volume: 8887776666666666666666666666666666666666666666666666666666555554 Timbre 4 @b30a (3931a): Duty cycle: 1111111111111111111111111111111111111111111111111111111111111111 Volume: 3345566677777777776666555555555544444433333222222222222222111111 Timbre 5 @b361 (39371): Duty cycle: 1111111111111111111111111111111111111111111111111111111111111111 Volume: a987665544332221766554433322211054433322221111003222111111111000 Timbre 6 @b1ed (391fd): Duty cycle: 0111111111111111111111111111111111111111111111111111111111111111 Volume: a987665544333222111111000000000000000000000000000000000000000000 Timbre 7 @b3a1 (393b1): Duty cycle: 2301111111111111111111111111111111111111111111111111111111111111 Volume: ba98765432111111111111111111111111111111111111110000000000000000 Code to set the initial index in an envelope (i.e. the envelope length): E756 CMP #$13 E758 BCC $E75E E75A LDA #$3F E75C BNE $E760 E75E LDA #$16 Code to read an envelope address: E78E CMP #$13 E790 BCC $E79E E792 LDA $E765,X E795 STA $71 E797 LDA $E766,X E79A STA $72 E79C BNE $E7A8 E79E LDA $E775,X E7A1 STA $71 E7A3 LDA $E776,X E7A6 STA $72 Track, Fanfare, and Block Tables To briefly explain the format of the tables: Bank 1 @ 1c:a76c (3877c) a73f (3874f) a86c (3887c) a87b (3888b) a88a (3889a): - Block header block address: $a76c in bank $1c (file offset $3877c) - Block offset table address: $a73f - Track first block table address: $a86c - Track last block table address: $a87b - Track loop block table address: $a88a Block 1 (1) @+8d: 3 abb1 (38bc1) +26 +11 +0 +38 - Block header offset in the block header block: $8d - Tempo index: 3 (150 BPM) (the actual value of this byte is $30) - Block base address: $abb1 (this is also the address of the square 2 channel data) - Triangle channel data offset: $26 - Square 1 channel data offset: $11 - Noise channel data offset: 0 (no noise channel for this block) - DMC channel data offset: $38 Note: Duplicate (repeated) block headers within the same track are abbreviated to make it more obvious that they are duplicates. Bank 1 @ 1c:a76c (3877c) a73f (3874f) a86c (3887c) a87b (3888b) a88a (3889a): Fanfare 1: Death Block 1 (1) @+8d: 3 abb1 (38bc1) +26 +11 +0 +38 Fanfare 2: Game Over Block 2 (2) @+a6: 3 ab35 (38b45) +20 +12 +0 +0 Fanfare 3: Recovered Scepter Block 3 (3) @+94: 3 aae7 (38af7) +21 +11 +0 +31 Fanfare 4: Rescued Kings Block 4 (4) @+ad: 4 abff (38c0f) +4d +27 +0 +73 Fanfare 5: Bowser's Fall Block 5 (5) @+fa: 3 a8d0 (388e0) +6f +4c +0 +ba Fanfare 6: Stage Clear Block 6 (6) @+9b: 3 a9f7 (38a07) +1f +10 +2e +3c Fanfare 7: Hurry Up Block 7 (7) @+86: 8 ab65 (38b75) +35 +18 +0 +0 Fanfare 8: Silence Block 8 (8) @+a2: 6 a8ad (388bd) +0 +30 +35 +ab Track 1 (1): Grass Land (World 1) Block 9 (9) @+3f: 5 af3b (38f4b) +7f +31 +b5 +ce (loop point) Block 10 (a) @+54: 5 b024 (39034) +40 +1c +5b +84 Track 2 (2): Desert Land (WOrld 2) Block 11 (b) @+31: 0 ad02 (38d12) +1b +e +2f +33 (loop point) Track 3 (3): Water Land (WOrld 3) Block 12 (c) @+46: 3 adce (38dde) +40 +37 +60 +72 (loop point) Block 13 (d) @+4d: 3 ae54 (38e64) +40 +37 +60 +85 Track 4 (4): Giant Land (World 4) Block 14 (e) @+23: 3 ac99 (38ca9) +20 +a +61 +65 (loop point) Track 5 (5): Sky Land Ground (World 5) Block 15 (f) @+38: 3 adc0 (38dd0) +0 +0 +0 +7 Block 16 (10) @+2a: 3 ad3b (38d4b) +56 +2d +7a +81 (loop point) Track 6 (6): Ice Land (World 6) Block 17 (11) @+6a: 3 b0c9 (390d9) +25 +12 +2a +35 (loop point) Track 7 (7): Pipe Land (World 7) Block 18 (12) @+71: 1 b10a (3911a) +56 +17 +64 +7d (loop point) Block 19 (13) @+78: 1 b137 (39147) +29 +15 +37 +50 Track 8 (8): Dark Land (World 8) Block 20 (14) @+62: 0 af15 (38f25) +13 +a +0 +1c (loop point) Track 9 (9): Sky Land Sky (World 5) Block 21 (15) @+1c: 0 aa3f (38a4f) +2e +19 +0 +0 (loop point) Track 10 (a): Star Power Block 22 (16) @+7f: 8 aa8e (38a9e) +37 +1a +49 +4f (loop point) Track 11 (b): Warp Zone Block 23 (17) @+15: 0 a990 (389a0) +0 +b +0 +0 Block 24 (18) @+1c: 0 aa3f (38a4f) +2e +19 +0 +0 (loop point) Track 12 (c): Music Box Block 25 (19) @ +0: 0 a9a7 (389b7) +0 +13 +0 +0 (loop point) Block 26 (1a) @ +7: 0 a9c6 (389d6) +0 +f +0 +0 Block 27 (1b) @ +0 Block 28 (1c) @ +e: 0 a9e2 (389f2) +0 +a +0 +0 Track 13 (d): Cursed Kings Block 29 (1d) @+b4: 3 a89a (388aa) +29 +14 +0 +0 (loop point) Track 14 (e): Spade House Block 30 (1e) @+5b: 5 aefe (38f0e) +7 +4 +10 +0 (loop point) Track 15 (f): Ending Block 31 (1f) @+bb: 0 c27a (3a28a) +0 +1b +0 +0 Block 32 (20) @+bb Block 33 (21) @+c2: 0 c2a6 (3a2b6) +0 +21 +0 +0 Block 34 (22) @+bb Block 35 (23) @+c9: 3 c2d8 (3a2e8) +23 +12 +33 +40 Block 36 (24) @+d0: 3 c333 (3a343) +45 +23 +65 +72 (loop point) Block 37 (25) @+d0 Block 38 (26) @+d7: 3 c3b2 (3a3c2) +1f +10 +32 +3f Block 39 (27) @+d7 Block 40 (28) @+de: 3 c3fe (3a40e) +39 +1d +5e +6b Block 41 (29) @+e5: 3 c476 (3a486) +6d +24 +a4 +b1 Block 42 (2a) @+ec: 3 c534 (3a544) +24 +c +37 +44 Block 43 (2b) @+e5 Block 44 (2c) @+f3: 3 c585 (3a595) +23 +f +3d +4a Bank 2 @ 1c:b42d (3943d) b3ff (3940f) b52f (3953f) b53b (3954b) b547 (39557): Track 1 (1): Overworld Theme 1 Block 1 (1) @+69: 3 b554 (39564) +29 +18 +41 +45 Block 2 (2) @+70: 3 b5a9 (395b9) +54 +2c +af +be (loop point) Block 3 (3) @+77: 3 b5c3 (395d3) +50 +2b +95 +a4 Block 4 (4) @+70 Block 5 (5) @+7e: 3 b629 (39639) +21 +12 +2f +48 Block 6 (6) @+85: 3 b68a (3969a) +69 +35 +7a +89 Block 7 (7) @+8c: 3 b71d (3972d) +5f +30 +72 +81 Track 2 (2): Underworld Theme Block 8 (8) @+bd: 5 c073 (3a083) +4b +0 +ae +95 (loop point) Track 3 (3): Underwater Theme Block 9 (9) @+54: 0 bbe7 (39bf7) +19 +d +0 +0 Block 10 (a) @+5b: 0 bc07 (39c17) +37 +1c +b2 +b8 (loop point) Block 11 (b) @+5b Block 12 (c) @+62: 0 bc5f (39c6f) +39 +1d +5a +60 Track 4 (4): Fortress Theme Block 13 (d) @+38: 0 c218 (3a228) +1f +10 +0 +2e (loop point) Block 14 (e) @+38 Block 15 (f) @+3f: 0 c251 (3a261) +15 +a +0 +1e Track 5 (5): Koopa Kids Block 16 (10) @+c4: 4 bcc5 (39cd5) +31 +19 +3c +59 Block 17 (11) @+cb: 4 bd3f (39d4f) +45 +23 +5c +62 (loop point) Block 18 (12) @+cb Block 19 (13) @+d2: 4 bda7 (39db7) +45 +23 +64 +6a Track 6 (6): Airship Theme Block 20 (14) @+46: 0 c124 (3a134) +19 +d +0 +29 (loop point) Block 21 (15) @+4d: 0 c167 (3a177) +51 +29 +7d +88 Track 7 (7): Hammer Bros. Block 22 (16) @+a1: 3 b87a (3988a) +d +7 +0 +13 Block 23 (17) @+a8: 3 b8a5 (398b5) +2b +0 +3c +42 Block 24 (18) @+a8 Block 25 (19) @+af: 3 b8a8 (398b8) +28 +16 +39 +3f (loop point) Block 26 (1a) @+af Block 27 (1b) @+b6: 3 b8ed (398fd) +43 +22 +64 +85 Track 8 (8): Toad's House Block 28 (1c) @+93: 0 c000 (3a010) +27 +14 +0 +70 (loop point) Block 29 (1d) @+93 Block 30 (1e) @+9a: 0 c038 (3a048) +27 +14 +0 +38 Track 9 (9): Overworld Theme 2 Block 31 (1f) @ +0: 3 b999 (399a9) +21 +11 +0 +0 Block 32 (20) @ +7: 3 b9c1 (399d1) +32 +15 +73 +83 (loop point) Block 33 (21) @ +e: 3 ba02 (39a12) +23 +12 +32 +42 Block 34 (22) @+15: 3 b9c1 (399d1) +32 +29 +73 +83 Block 35 (23) @+1c: 3 ba53 (39a63) +52 +29 +7b +8b Block 36 (24) @+23: 3 bb04 (39b14) +26 +15 +68 +6e Block 37 (25) @+2a: 3 bb3a (39b4a) +23 +13 +32 +38 Block 38 (26) @+23 Block 39 (27) @+31: 3 bb79 (39b89) +36 +1c +46 +59 Track 10 (a): Toad's House Block 28 (1c) @+93: 0 c000 (3a010) +27 +14 +0 +70 (loop point) Block 29 (1d) @+93 Block 30 (1e) @+9a: 0 c038 (3a048) +27 +14 +0 +38 Track 11 (b): Bowser Battle Block 40 (28) @+d9: 7 b7c3 (397d3) +1b +e +28 +0 Block 41 (29) @+e0: 7 b7f8 (39808) +43 +22 +6e +78 (loop point) Block 42 (2a) @+e7: 7 b7f8 (39808) +48 +22 +6e +78 Block 43 (2b) @+ee: 7 b7f8 (39808) +53 +22 +6e +78 Block 44 (2c) @+f5: 7 b7f8 (39808) +65 +22 +6e +78 Track 12 (c): Unused Block 45 (2d) @+fc: 4 bcc5 (39cd5) +31 +19 +0 +0 (loop point) Bank 1 Track Structures Code to load the block indices for a track (bank $1f): E417 LDA $A86C,Y E41A STA $7AE0 E41D LDA $A87B,Y E420 CLC E421 ADC #$02 E423 STA $7AE1 E426 LDA $A88A,Y E429 STA $7AE2 Code to load the block header offset and then load the parameters from the header: E45A LDA $A73F,Y E45D TAY E45E LDA $A76C,Y E461 STA $04FD E464 LDA $A76D,Y E467 STA $6B E469 LDA $A76E,Y E46C STA $6C E46E LDA $A76F,Y E471 STA $04D0 E474 LDA $A770,Y E477 STA $04FF E47A LDA $A771,Y E47D STA $04D1 E480 STA $07F3 E483 LDA $A772,Y E486 STA $04D2 E489 STA $04DE Bank 2 Track Structures Code to load the block indices for a track: E388 LDA $B52F,Y E38B STA $7AE0 E38E LDA $B53B,Y E391 CLC E392 ADC #$02 E394 STA $7AE1 E397 LDA $B547,Y E39A STA $7AE2 Code to load the block header offset and then load the parameters from the header: E3B6 LDA $B3FF,Y E3B9 TAY E3BA LDA $B42D,Y E3BD STA $04FD E3C0 LDA $B42E,Y E3C3 STA $6B E3C5 LDA $B42F,Y E3C8 STA $6C E3CA LDA $B430,Y E3CD STA $04D0 E3D0 LDA $B431,Y E3D3 STA $04FF E3D6 LDA $B432,Y E3D9 STA $04D1 E3DC STA $07F3 E3DF LDA $B433,Y E3E2 STA $04D2 E3E5 STA $04DE Revisions v1.1: - As it turns out, the way SMB3 mixes 0-based and 1-based indexing is so confusing I got confused writing the spec. This revision fixes that error and attempts to clarify the subject so as to prevent any further mishaps. - Add table of noise preset characteristics - Unhid the unused track that was previously hidden because it's junk - Various other small changes meant to increase clarity